
public class MainEjercicio2 {
        public static void main(String[] args) {
            
            int iterationNumber[] = {10,100,1000,5000};
            int neuronSize[] = {4,12,48};

            System.out.printf("\n Pruebas para la primera funcion: f(x) = x \n" );               
            for (int i =0 ; i < neuronSize.length ; i++) {
                for (int j =0 ; j < iterationNumber.length ; j++) {
                    System.out.printf("\n Cantidad de Neuronas: %d , Cantidad de iteraciones: %d\n", neuronSize[i], iterationNumber[j] );        
                    testFuncion1Tanh(iterationNumber[j],neuronSize[i],20);
                }
            }

            System.out.printf("\n Pruebas para la segunda funcion: f(x) = x^4 usando Sigmoide\n" );               

            for (int i =0 ; i < neuronSize.length ; i++) {
                for (int j =0 ; j < iterationNumber.length ; j++) {
                    System.out.printf("\n Cantidad de Neuronas: %d , Cantidad de iteraciones: %d\n", neuronSize[i], iterationNumber[j] );        
                    testFuncion2Sigmoide(iterationNumber[j],neuronSize[i],20);
                }
            }            
            
            System.out.printf("\n Pruebas para la segunda funcion: f(x) = sin(3/2)*pi*x \n" );               

            for (int i =0 ; i < neuronSize.length ; i++) {
                for (int j =0 ; j < iterationNumber.length ; j++) {
                    System.out.printf("\n Cantidad de Neuronas: %d , Cantidad de iteraciones: %d\n", neuronSize[i], iterationNumber[j] );        
                    testFuncion3Tanh(iterationNumber[j],neuronSize[i],20);
                }
            }           
             
        }
        
    public static void  testFuncion6Cuadrado( int maxIteration, int hiddenNumberOfNeurons , int learningSetSize ) {
        testGeneric(maxIteration, hiddenNumberOfNeurons,learningSetSize,3,2,0);
        
    }         
    
    public static void  testFuncion5Lineal( int maxIteration, int hiddenNumberOfNeurons , int learningSetSize ) {
        testGeneric(maxIteration, hiddenNumberOfNeurons,learningSetSize,2,1,0);
        
    }            
        
    //Representa a la funcion f(x) = x^4, entre 0 y 1 usando sigmoide
    public static void  testFuncion2Sigmoide( int maxIteration, int hiddenNumberOfNeurons , int learningSetSize ) {
        //0:Funcion de activacion sigmoide, 2: uso la funcion 2f(x) = x^4 , 1:uso el rango 0 a 1
        testGeneric(maxIteration, hiddenNumberOfNeurons,learningSetSize,0,2,1);
        
    }        
    
   //Representa a la funcion f(x) = x, entre -1 y 1
    public static void  testFuncion1Tanh( int maxIteration, int hiddenNumberOfNeurons , int learningSetSize ) {
        
        //1:Funcion de activacion tanh, 1: uso la funcion 3( f(x) = x , 0:uso el rango default -1 a 1
        testGeneric(maxIteration, hiddenNumberOfNeurons,learningSetSize,1,1,0);
        

    }            
    
    
   //Representa a la funcion f(x) = x^4, entre -1 y 1
    public static void  testFuncion2Tanh( int maxIteration, int hiddenNumberOfNeurons , int learningSetSize ) {
        
        //1:Funcion de activacion tanh, 3: uso la funcion 3( f(x) = x^4 , 0:uso el rango default -1 a 1
        testGeneric(maxIteration, hiddenNumberOfNeurons,learningSetSize,1,2,0);
        
    }      
    
 //Representa a la funcion f(x) = sen(3/2*pi*x), entre -1 y 1
    public static void  testFuncion3Tanh( int maxIteration, int hiddenNumberOfNeurons , int learningSetSize ) {
        
        //1:Funcion de activacion tanh, 3: uso la funcion 3( f(x) = sen(3/2*pi*x)) , 0:uso el rango default -1 a 1
        testGeneric(maxIteration, hiddenNumberOfNeurons,learningSetSize,1,3,0);
        
    }   
    
    
    
    public static void  testGeneric( int maxIteration, int hiddenNumberOfNeurons , int learningSetSize, int activation, int functionType , int range ) {
        
        NeuralNetwork net = new NeuralNetwork( maxIteration, hiddenNumberOfNeurons, learningSetSize, activation);
        
        int pointsNumber = 20;
        net.learningSetInput = new double[pointsNumber][1];
        net.learningSetOutput = new double[pointsNumber][1];
        double fx = 0;

        //Default range -1 a 1
        double factor = 1/((double)pointsNumber/2); 
        double x = -1 - factor;
        //rango de 0 a 1
        if (range == 1 ) { 
            factor = 1/((double)pointsNumber); 
            x = -factor;      
        }

        for (int i = 0; i < pointsNumber ; i++) {
            x += factor ; 
            
            if (functionType == 1) {
                fx = x;
            } else if (functionType == 2) {
                fx = Math.pow(x,4);
            } else if (functionType == 3) {
                fx = Math.sin((3/2)*Math.PI*x);
            }
            net.learningSetInput[i] = new double [] {x};
            net.learningSetOutput[i] = new double [] {fx};
        }

        net.training();

        //Usamos el mismo set de entrada para analizar el error.
        net.testingSetInput = net.learningSetInput;
        net.testingSetOutput = net.learningSetOutput;
        

        //System.out.printf("     I |  Real   | Evaluado|  Diff\n" );        
        
        for (int i = 0; i < net.testingSetInput.length; i++) {
            double diff = (net.evaluate(net.testingSetInput[i]) - net.learningSetOutput[i][0]);
            System.out.printf("%6.2f | %7.4f | %7.4f | %7.4f \n" ,net.testingSetInput[i][0], net.learningSetOutput[i][0], net.evaluate(net.testingSetInput[i]),diff  );        
        }

        /*System.out.printf("\n Errores para cantidad de nuronas: %s \n", hiddenNumberOfNeurons);
        //Ahora mostramos los errores para cada una de las cantidad de hidden 
        for (int j =0 ; j < net.errorsArray.length ; j++) {
            if (j%100 == 0)
                System.out.printf("| %7.4f |\n", net.errorsArray[j] );        
        } */    
        System.out.println("GlobalError: " + net.getGlobalError());

    }    
}
